package com.wl.cloud.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.wl.cloud.core.dto.DataStoreDTO;
import com.wl.cloud.core.utils.PageUtils;
import com.wl.cloud.system.dao.SysRoleMenuMapper;
import com.wl.cloud.system.domain.SysRoleMenu;
import com.wl.cloud.system.service.SysRoleMenuService;
import com.wl.cloud.system.support.dto.SysRoleMenuDTO;
import com.wl.cloud.system.support.dto.query.SysRoleMenuQueryDTO;
import com.wl.cloud.system.support.enums.RoleTypeEnum;
import com.wl.cloud.system.support.vo.SysRoleMenuVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 角色菜单表 服务实现类
 *
 * @author wanglin
 * @since 2023-09-18
 */
@Service
public class SysRoleMenuServiceImpl implements SysRoleMenuService {

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Transactional(readOnly = true)
    @Override
    public DataStoreDTO<SysRoleMenuVO> page(Pageable pageable, SysRoleMenuQueryDTO queryDto) {
        QueryWrapper<SysRoleMenu> queryWrapper = this.buildQuery(queryDto);
        Page<SysRoleMenu> page = PageUtils.transferPage(pageable);
        Page<SysRoleMenu> result = this.sysRoleMenuMapper.selectPage(page, queryWrapper);
        return new DataStoreDTO(result.getTotal(), this.transferVo(result.getRecords()));
    }

    @Transactional(readOnly = true)
    @Override
    public List<SysRoleMenuVO> list(Sort sort, SysRoleMenuQueryDTO queryDto) {
        QueryWrapper<SysRoleMenu> queryWrapper = this.buildQuery(queryDto);
        PageUtils.transferSort(queryWrapper, sort);
        return this.transferVo(this.sysRoleMenuMapper.selectList(queryWrapper));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysRoleMenuDTO dto) {
        // TODO 唯一性字段校验
        dto.setId(null);
        sysRoleMenuMapper.insert(this.transferEntity(null, dto));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SysRoleMenuDTO dto) {
        Assert.hasText(dto.getId(), "id不能为空");
        // TODO 唯一性字段校验
        SysRoleMenu entity = sysRoleMenuMapper.selectById(dto.getId());
        Assert.notNull(entity, "找不到id为 " + dto.getId() + " 的记录");
        sysRoleMenuMapper.updateById(this.transferEntity(entity, dto));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Set<String> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            sysRoleMenuMapper.deleteBatchIds(ids);
        }
    }

    @Transactional(readOnly = true)
    @Override
    public SysRoleMenuVO get(String id) {
        Assert.hasText(id, "id不能为空");
        SysRoleMenu entity = sysRoleMenuMapper.selectById(id);
        Assert.notNull(entity, "找不到id为 " + id + " 的记录");
        return this.transferVo(entity);
    }

    @Transactional(readOnly = true)
    @Override
    public List<SysRoleMenu> getListByRoleId(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            return Lists.newArrayList();
        }
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRoleMenu::getRoleId, roleId);
        return sysRoleMenuMapper.selectList(queryWrapper);
    }

    @Transactional(readOnly = true)
    @Override
    public List<SysRoleMenu> getListByRoleId(String roleId, String roleType) {
        //若是管理员，则直接全部集合
        if (RoleTypeEnum.ADMIN.getKey().equals(roleType)) {
            return sysRoleMenuMapper.selectList(null);
        } else {
            return this.getListByRoleId(roleId);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByRoleIds(List<String> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            sysRoleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds));
        }
    }

    private QueryWrapper<SysRoleMenu> buildQuery(SysRoleMenuQueryDTO queryDto) {
        QueryWrapper<SysRoleMenu> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(queryDto)) {
            queryWrapper.lambda().eq(StringUtils.isNotBlank(queryDto.getId()), SysRoleMenu::getId, queryDto.getId());
        }
        return queryWrapper;
    }

    private SysRoleMenu transferEntity(SysRoleMenu entity, SysRoleMenuDTO dto) {
        if (Objects.isNull(entity)) {
            entity = new SysRoleMenu();
        }
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }

    private List<SysRoleMenuVO> transferVo(List<SysRoleMenu> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return Lists.newArrayList();
        }

        List<SysRoleMenuVO> voList = entities.stream().map(entity -> {
            SysRoleMenuVO vo = new SysRoleMenuVO();
            BeanUtils.copyProperties(entity, vo);
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    private SysRoleMenuVO transferVo(SysRoleMenu entity) {
        if (Objects.isNull(entity)) {
            return null;
        }
        SysRoleMenuVO vo = new SysRoleMenuVO();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
